package com.wenju.inappupdatemodule.net;

import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;

import com.wenju.inappupdatemodule.R;
import com.wenju.inappupdatemodule.bean.UpdateEntity;
import com.wenju.inappupdatemodule.service.DownloadService;
import com.wenju.inappupdatemodule.utils.UpdateHelper;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import static android.content.Context.NOTIFICATION_SERVICE;


public class UpdateAgent {
    private static UpdateAgent updater;
    //下载的进度弹窗
    private ProgressDialog downDialog;
    //下载进度的广播
    private UpdateProgressBroadcastReceiver broadcastReceiver;

    public static UpdateAgent getInstance() {
        if (updater == null) {
            updater = new UpdateAgent();
        }
        return updater;
    }

    /**
     * 没有更新的dialog
     */
    public void showNoUpdateDialog(final Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(UpdateHelper.getInstance().getmNoUpdateDialogTitle());
        builder.setMessage(UpdateHelper.getInstance().getmNoUpdateDialogContext());
        builder.setCancelable(false);
        builder.setPositiveButton(UpdateHelper.getInstance().getmNoUpdateDialogConfirm(), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.show();
    }

    /**
     * 有更新的dialog
     *
     * @param updateEntity 应用更新实体类
     */
//    private boolean isDialogShow = true;

    public void showAlertDialog(final Activity activity, final UpdateEntity updateEntity, boolean isForcedUpdate) {
//        if (isDialogShow) {
//            isDialogShow = false;
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle(UpdateHelper.getInstance().getmNewUpdateTitle());
            builder.setMessage(updateEntity.getContent());
            builder.setCancelable(false);
            builder.setPositiveButton(UpdateHelper.getInstance().getmNewUpdatePositiveButton(), new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    downloadApp(activity, updateEntity);
                }
            });
            if (!isForcedUpdate) {
                builder.setNegativeButton(UpdateHelper.getInstance().getmNewUpdateNegativeButton(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
            }
            builder.show();
//        }
    }

    /**
     * 下载APP
     *
     * @param updateEntity 应用更新实体类
     */
    public void downloadApp(final Activity activity, final UpdateEntity updateEntity) {
        if(ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //为了首次安装，下方直接进行判断
                createNotification(activity);
                if (!isNotificationEnabled(activity)) {
                    showSettingDialog(activity,updateEntity);
                } else {
                    NotificationManager manager = (NotificationManager) activity.getSystemService(NOTIFICATION_SERVICE);
                    assert manager != null;
                    final NotificationChannel channel = manager.getNotificationChannel(UpdateHelper.getInstance().getmNotificationChannelId());
                    if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                        new AlertDialog.Builder(activity)
                                .setTitle(R.string.str_tip)
                                .setMessage(R.string.wj_str_open_notification_hint)
                                .setCancelable(false)
                                .setPositiveButton(R.string.str_confirm, new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int id) {
                                        try {
//                                            isDialogShow = true;
                                            Intent notificationSettingTypeIntent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
                                            notificationSettingTypeIntent.putExtra(Settings.EXTRA_APP_PACKAGE, activity.getPackageName());
                                            notificationSettingTypeIntent.putExtra(Settings.EXTRA_CHANNEL_ID, UpdateHelper.getInstance().getmNotificationChannelId());
                                            activity.startActivity(notificationSettingTypeIntent);
                                        } catch (Exception e) {
                                            Toast.makeText(activity, activity.getString(R.string.str_skip_abnormal), Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                })
                                .setNegativeButton(activity.getString(R.string.str_cancel), new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        dialog.dismiss();
                                        downProgressDialog(activity,updateEntity);
                                    }
                                })
                                .show();
                    }else{
                        downProgressDialog(activity,updateEntity);
                    }
                }
            }else {
                downProgressDialog(activity,updateEntity);
            }
        }else{
            Toast.makeText(activity,UpdateHelper.getInstance().getmDownFail(), Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 下载时的进度条弹窗
     *
     * @param activity
     */
    private void downProgressDialog(final Activity activity, final UpdateEntity updateEntity) {
        //判断服务是否运行，防止重复启动产生错误
        if (!isServiceWork(activity, DownloadService.class.getName())) {
            Intent it = new Intent(activity, DownloadService.class);
            it.putExtra(DownloadService.KEY_APP_NAME, updateEntity.getAppName());
            it.putExtra(DownloadService.KEY_DOWN_URL, updateEntity.getUpdateUrl());
            //是否自动安装
            if (UpdateHelper.getInstance().getDownType() == UpdateHelper.DownType.down_auto_Install) {
                it.putExtra(DownloadService.KEY_AUTO_INSTALL, true);
            } else {
                it.putExtra(DownloadService.KEY_AUTO_INSTALL, false);
            }
            activity.startService(it);
            //判断是否显示进度弹窗
            if (UpdateHelper.getInstance().isShowProgressDialog()) {
                // 动态注册广播
                IntentFilter filter = new IntentFilter();
                filter.addAction(DownloadService.ACTION_BROADCAST);
                broadcastReceiver = new UpdateProgressBroadcastReceiver();
                activity.registerReceiver(broadcastReceiver, filter);

                downDialog = new ProgressDialog(activity);
                downDialog.setTitle(UpdateHelper.getInstance().getmDwonProgressDialogTitle());
                downDialog.setCancelable(false);
                downDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                downDialog.setButton(
                        ProgressDialog.BUTTON_POSITIVE,
                        UpdateHelper.getInstance().getmDownProgressDialogPositiveButton(),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        });

                downDialog.setButton(
                        ProgressDialog.BUTTON_NEGATIVE,
                        UpdateHelper.getInstance().getmDownProgressDialogNegativeButton(),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                UpdateHelper.getInstance().setDownloadCancle(true);
                            }
                        });

                downDialog.show();
                downDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialogInterface) {
                        // 注销广播
                        if (broadcastReceiver != null) {
                            activity.unregisterReceiver(broadcastReceiver);
                        }
                    }
                });
            }
        } else {
            Toast.makeText(activity, UpdateHelper.getInstance().getmContinuouslyOpenServicePrompts(), Toast.LENGTH_SHORT).show();
        }
    }

    private static onProgressChangedListener mOnProgressChangedListener;

    /**
     * 定义广播接收器
     */
    private class UpdateProgressBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            int type = intent.getIntExtra(DownloadService.KEY_BROADCAST_TYPE, -1);

            if (type == DownloadService.DOWN_LOADING) {
                if (!downDialog.isShowing()) {
                    downDialog.show();
                }
                //更新弹窗进度
                downDialog.setMax(intent.getIntExtra(DownloadService.KEY_BROADCAST_TOTAL, 0) / 1000);
                downDialog.setProgress(intent.getIntExtra(DownloadService.KEY_BROADCAST_COUNT, 0) / 1000);


                mOnProgressChangedListener.onProgressChangedListenerChanged(intent.getIntExtra(DownloadService.KEY_BROADCAST_COUNT, 0) / 1000);
            }

            //关闭弹窗
            if (type == DownloadService.DOWN_SUCCESS) {
                if (downDialog != null) {
                    downDialog.dismiss();
                }
            }
            //关闭弹窗
            if (type == DownloadService.DOWN_ERROR) {
                if (downDialog != null) {
                    downDialog.dismiss();
                }
            }
        }
    }

    /**
     * 获取下载进度监听
     */
    public interface onProgressChangedListener {
        void onProgressChangedListenerChanged(int currentProgress);
    }

    public static void setOnProgressChangedListener(onProgressChangedListener listener) {
        mOnProgressChangedListener = listener;
    }


    /**
     * 判断某个服务是否正在运行的方法
     *
     * @param mContext
     * @param serviceName 是包名+服务的类名
     * @return true代表正在运行，false代表服务没有正在运行
     */
    public boolean isServiceWork(Context mContext, String serviceName) {
        ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(40);
        for (int i = 0; i < myList.size(); i++) {
            String mName = myList.get(i).service.getClassName();
            if (mName.equals(serviceName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 可以通过NotificationManagerCompat 中的 areNotificationsEnabled()来判断是否开启通知权限。NotificationManagerCompat 在 android.support.v4.app包中，是API 22.1.0 中加入的。而 areNotificationsEnabled()则是在 API 24.1.0之后加入的。
     * areNotificationsEnabled 只对 API 19 及以上版本有效，低于API 19 会一直返回true
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static boolean isNotificationEnabled(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
            boolean areNotificationsEnabled = notificationManagerCompat.areNotificationsEnabled();
            return areNotificationsEnabled;
        }

        String CHECK_OP_NO_THROW = "checkOpNoThrow";
        String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        ApplicationInfo appInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = appInfo.uid;

        Class appOpsClass = null;
        /* Context.APP_OPS_MANAGER */
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

    }

    private void showSettingDialog(final Activity activity, final UpdateEntity updateEntity) {
        new AlertDialog.Builder(activity)
                .setTitle(R.string.str_tip)
                .setMessage(R.string.wj_str_open_notification)
                .setCancelable(false)
                .setPositiveButton(R.string.str_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        gotoSetNotification(activity);
//                        isDialogShow = true;
                    }
                })
                .setNegativeButton(activity.getString(R.string.str_cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        downProgressDialog(activity,updateEntity);
                    }
                })
                .show();
    }

    /**
     * 假设没有开启通知权限，点击之后就需要跳转到 APP的通知设置界面，对应的Action是：Settings.ACTION_APP_NOTIFICATION_SETTINGS, 这个Action是 API 26 后增加的
     * 如果在部分手机中无法精确的跳转到 APP对应的通知设置界面，那么我们就考虑直接跳转到 APP信息界面，对应的Action是：Settings.ACTION_APPLICATION_DETAILS_SETTINGS
     */
    private static void gotoSetNotification(Context context) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= 26) {
            // android 8.0引导
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
        } else if (Build.VERSION.SDK_INT >= 21) {
            // android 5.0-7.0
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else {
            // 其他
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    public void createNotification(final Activity activity) {
        /**
         * 方法描述：createNotification方法
         * @param
         * @return
         * @see DownloadService
         */
        //通知
        NotificationManager mNotificationManager1 = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification.Builder builder;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel downloadChannel = new NotificationChannel(
                    UpdateHelper.getInstance().getmNotificationChannelId(),
                    UpdateHelper.getInstance().getmNotificationName(),
                    NotificationManager.IMPORTANCE_HIGH);
            downloadChannel.setSound(null, null);
            downloadChannel.setVibrationPattern(null);
            mNotificationManager1.createNotificationChannel(downloadChannel);
            builder = new Notification.Builder(activity.getApplicationContext(), UpdateHelper.getInstance().getmNotificationChannelId());
        } else {
            builder = new Notification.Builder(activity.getApplicationContext());
        }
        builder.setSmallIcon(UpdateHelper.getmBuliderSmallIcon());
        builder.setTicker(UpdateHelper.getInstance().getmBuilderTicker());
        builder.setContentText(UpdateHelper.getInstance().getmBuilderContext());
        builder.setNumber(0);
        builder.setShowWhen(true);
        builder.setOngoing(true);
        builder.setAutoCancel(false);
        mNotificationManager1.notify(0x10000, builder.build());
    }

}
